package com.dge.common.extentions

import android.content.Context
import android.graphics.Color
import android.graphics.drawable.GradientDrawable
import android.os.Build
import android.view.View
import android.view.ViewGroup
import android.widget.EdgeEffect
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.SimpleItemAnimator
import androidx.recyclerview.widget.StaggeredGridLayoutManager
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.viewholder.QuickViewHolder
import com.dge.common.other.StretchEdgeEffect
import com.dge.common.utils.RecyclerViewDivider
import com.google.android.flexbox.FlexboxLayoutManager
import java.util.Collections

/**
 * Description: RecyclerView扩展
 * Create by lxj, at 2018/12/25
 */
/**
 * 设置分割线
 * @param color 分割线的颜色，默认是#DEDEDE
 * @param size 分割线的大小，默认是1px
 * @param isReplace 是否覆盖之前的ItemDecoration，默认是true
 *
 */
fun RecyclerView.divider(
    color: Int = Color.parseColor("#f5f5f5"),
    size: Int = 1f.dp.toInt(),
    isReplace: Boolean = true
): RecyclerView {
    val decoration = RecyclerViewDivider(context, orientation)
    decoration.setDrawable(GradientDrawable().apply {
        setColor(color)
        shape = GradientDrawable.RECTANGLE
        setSize(size, size)
    })
    if (isReplace && itemDecorationCount > 0) {
        removeItemDecorationAt(0)
    }
    addItemDecoration(decoration)
    return this
}

fun RecyclerView.flexbox(): RecyclerView {
    layoutManager = FlexboxLayoutManager(context)
    return this
}

fun RecyclerView.vertical(spanCount: Int = 0, isStaggered: Boolean = false): RecyclerView {
    layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
    if (spanCount != 0) {
        layoutManager = GridLayoutManager(context, spanCount)
    }
    if (isStaggered) {
        layoutManager = StaggeredGridLayoutManager(spanCount, StaggeredGridLayoutManager.VERTICAL)
    }
    return this
}

fun RecyclerView.horizontal(spanCount: Int = 0, isStaggered: Boolean = false): RecyclerView {
    layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
    if (spanCount != 0) {
        layoutManager = GridLayoutManager(context, spanCount, GridLayoutManager.HORIZONTAL, false)
    }
    if (isStaggered) {
        layoutManager = StaggeredGridLayoutManager(spanCount, StaggeredGridLayoutManager.HORIZONTAL)
    }
    return this
}

inline val RecyclerView.data
    get() = (adapter as BaseQuickAdapter<*, QuickViewHolder>).items
inline val RecyclerView.orientation
    get() = if (layoutManager == null) -1 else layoutManager.run {
        when (this) {
            is LinearLayoutManager -> orientation
            is GridLayoutManager -> orientation
            is StaggeredGridLayoutManager -> orientation
            else -> -1
        }
    }

fun <T : Any> RecyclerView.bindData(
    data: ArrayList<T>,
    layoutId: Int,
    bindFn: (holder: QuickViewHolder, item: T?, position: Int) -> Unit
): RecyclerView {
    adapter = object : BaseQuickAdapter<T, QuickViewHolder>(data) {
        override fun onBindViewHolder(holder: QuickViewHolder, position: Int, item: T?) {
            bindFn(holder, item, holder.layoutPosition)
        }

        override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): QuickViewHolder {
            return QuickViewHolder(layoutId, parent)
        }
    }
    return this
}

// const val WHAT_SET_LAST_POSITION = 0x100
fun <T : Any> RecyclerView.updateData(data: MutableList<T>) {
    val adapter = adapter as? BaseQuickAdapter<T, QuickViewHolder>?
    adapter?.submitList(data)
}

// /**
//  * 必须在bindData之后调用，并且需要hasHeaderOrFooter为true才起作用
//  */
// fun RecyclerView.addHeader(headerView: View): RecyclerView {
//     adapter?.apply {
//         (this as BaseQuickAdapter<*, QuickViewHolder>).addHeaderView(headerView)
//     }
//     return this
// }
//
// /**
//  * 必须在bindData之后调用，并且需要hasHeaderOrFooter为true才起作用
//  */
// fun RecyclerView.addFooter(footerView: View): RecyclerView {
//     adapter?.apply {
//         (this as BaseQuickAdapter<*, QuickViewHolder>).addFooterView(footerView)
//     }
//     return this
// }
// fun RecyclerView.addEmptyView(
//     emptyView: View,
//     callback: ((view: View) -> Unit)? = null
// ): RecyclerView {
//     adapter?.apply {
//         if (callback != null) {
//             callback(emptyView)
//         }
//         (this as BaseQuickAdapter<*, QuickViewHolder>).setEmptyView(emptyView)
//     }
//     return this
// }
// fun RecyclerView.addEmptyView(
//     layoutResId: Int,
//     callback: ((view: View) -> Unit)? = null
// ): RecyclerView {
//     val view = LayoutInflater.from(this.context).inflate(layoutResId, this, false)
//     adapter?.apply {
//         if (callback != null) {
//             callback(view)
//         }
//         (this as BaseQuickAdapter<*, QuickViewHolder>).setEmptyView(view)
//     }
//     return this
// }
// fun RecyclerView.multiTypes(
//     data: MutableList<MultiItemEntity>,
//     itemTypeAndLayout: MutableMap<Int, Int>,
//     bindFn: (holder: QuickViewHolder, item: MultiItemEntity) -> Unit
// ): RecyclerView {
//     adapter = object : BaseMultiItemQuickAdapter<MultiItemEntity, QuickViewHolder>(data) {
//         init {
//             itemTypeAndLayout.forEach { (t, u) ->
//                 addItemType(t, u)
//             }
//         }
//
//         override fun convert(holder: QuickViewHolder, item: MultiItemEntity) {
//             bindFn(holder, item)
//         }
//     }
//     return this
// }
fun <T : Any> RecyclerView.itemClick(listener: (data: MutableList<T>, view: View, position: Int) -> Unit): RecyclerView {
    //
    adapter?.apply {
        (adapter as BaseQuickAdapter<T, QuickViewHolder>).setOnItemClickListener { adapter, view, position ->
            listener(adapter.items as MutableList<T>, view, position)
        }
    }
    return this
}

fun <T : Any> RecyclerView.itemLongClick(listener: (data: MutableList<T>, view: View, position: Int) -> Unit): RecyclerView {
    adapter?.apply {
        (adapter as BaseQuickAdapter<T, QuickViewHolder>).setOnItemLongClickListener { adapter, view, position ->
            listener(adapter.items as MutableList<T>, view, position)
            true
        }
    }
    return this
}

// fun <T> RecyclerView.itemChildClickListener(
//     @IdRes vararg viewIds: Int,
//     listener: (data: MutableList<T>, view: View, position: Int) -> Unit
// ): RecyclerView {
//     adapter?.apply {
//         val baseAdapter = (adapter as BaseQuickAdapter<T, QuickViewHolder>)
//         for (id in viewIds) {
//             baseAdapter.addChildClickViewIds(id)
//         }
//         (adapter as BaseQuickAdapter<T, QuickViewHolder>).setOnItemChildClickListener { adapter, view, position ->
//             listener(adapter.data as MutableList<T>, view, position)
//         }
//     }
//     return this
// }
// fun <T> RecyclerView.itemChildLongClickListener(
//     @IdRes vararg viewIds: Int,
//     listener: (data: MutableList<T>, view: View, position: Int) -> Unit
// ): RecyclerView {
//     adapter?.apply {
//         val baseAdapter = (adapter as BaseQuickAdapter<T, QuickViewHolder>)
//         for (id in viewIds) {
//             baseAdapter.addChildClickViewIds(id)
//         }
//         (adapter as BaseQuickAdapter<T, QuickViewHolder>).setOnItemChildLongClickListener { adapter, view, position ->
//             listener(adapter.data as MutableList<T>, view, position)
//             true
//         }
//     }
//     return this
// }
fun RecyclerView.smoothScrollToEnd() {
    if (adapter != null && adapter!!.itemCount > 0) {
        smoothScrollToPosition(adapter!!.itemCount - 1)
    }
}

fun RecyclerView.scrollToEnd() {
    if (adapter != null && adapter!!.itemCount > 0) {
        scrollToPosition(adapter!!.itemCount - 1)
    }
}

/**
 * 滚动置顶，只支持线性布局
 */
fun RecyclerView.scrollTop(position: Int) {
    if (layoutManager is LinearLayoutManager) {
        (layoutManager as LinearLayoutManager).scrollToPositionWithOffset(position, 0)
    }
}

/**
 * 启用条目拖拽，必须在设置完adapter之后调用
 * @param isDisableLast 是否禁用最后一个拖拽
 */
fun RecyclerView.enableItemDrag(
    isDisableLast: Boolean = false,
    onDragFinish: (() -> Unit)? = null
) {
    ItemTouchHelper(object : ItemTouchHelper.Callback() {
        override fun getMovementFlags(
            recyclerView: RecyclerView,
            viewHolder: RecyclerView.ViewHolder
        ): Int {
            if (adapter == null) return 0
            if (isDisableLast && viewHolder.adapterPosition == (adapter!!.itemCount - 1)) return 0
            return if (recyclerView.layoutManager is GridLayoutManager) {
                val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN or
                        ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT
                val swipeFlags = 0
                makeMovementFlags(dragFlags, swipeFlags)
            } else {
                val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN
                val swipeFlags = 0
                makeMovementFlags(dragFlags, swipeFlags)
            }
        }

        override fun onMove(
            recyclerView: RecyclerView,
            viewHolder: RecyclerView.ViewHolder,
            target: RecyclerView.ViewHolder
        ): Boolean {
            if (adapter == null) return false
            //得到当拖拽的viewHolder的Position
            val fromPosition = viewHolder.adapterPosition
            //拿到当前拖拽到的item的viewHolder
            val toPosition = target.adapterPosition
            if (isDisableLast && toPosition == (adapter!!.itemCount - 1)) return false
            if (fromPosition < toPosition) {
                for (i in fromPosition until toPosition) {
                    Collections.swap((adapter as BaseQuickAdapter<*, QuickViewHolder>).items, i, i + 1)
                }
            } else {
                for (i in fromPosition downTo toPosition + 1) {
                    Collections.swap((adapter as BaseQuickAdapter<*, QuickViewHolder>).items, i, i - 1)
                }
            }
            recyclerView.adapter?.notifyItemMoved(fromPosition, toPosition)
            return true
        }

        override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {}

        override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
            super.onSelectedChanged(viewHolder, actionState)
        }

        override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {
            super.clearView(recyclerView, viewHolder)
            onDragFinish?.invoke()
        }
    }).attachToRecyclerView(this)
}

fun RecyclerView.disableItemChangeAnimation() {
    (itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
}

/**
 * android12 RecyclerView 过度滚动果冻效果
 */
fun RecyclerView.applyStretchEdgeEffect(@RecyclerView.Orientation orientation: Int = RecyclerView.VERTICAL) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
        this.edgeEffectFactory = object : RecyclerView.EdgeEffectFactory() {
            override fun createEdgeEffect(view: RecyclerView, direction: Int): EdgeEffect {
                return object : StretchEdgeEffect(view.context, view, orientation) {
                    var oldGlowScaleY = mGlowScaleY
                    override fun another(): StretchEdgeEffect {
                        if (direction == DIRECTION_BOTTOM || direction == DIRECTION_RIGHT) {
                            if (this.mGlowScaleY != 0f)
                                oldGlowScaleY = mGlowScaleY
                            this.mGlowScaleY = 0f
                        } else {
                            this.mGlowScaleY = oldGlowScaleY
                        }
                        return this
                    }

                    override fun pivotY(): Float {
                        return if (direction == DIRECTION_TOP || direction == DIRECTION_LEFT) {
                            0f
                        } else if (orientation == RecyclerView.VERTICAL) {
                            view.height * 1.0f
                        } else {
                            0f
                        }
                    }

                    override fun pivotX(): Float {
                        return if (direction == DIRECTION_LEFT) {
                            0f
                        } else if (orientation != RecyclerView.VERTICAL) {
                            view.width * 1.0f
                        } else {
                            0f
                        }
                    }
                }
            }
        }
    }
}